package com.ryan.mdp.json;

import java.io.IOException;

import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.JsonParser;
import org.codehaus.jackson.JsonProcessingException;
import org.codehaus.jackson.JsonToken;
import org.codehaus.jackson.map.DeserializationContext;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.deser.std.StdDeserializer;
import org.springframework.util.ClassUtils;

public class MdpInvocationResultDeserializer extends StdDeserializer<MdpInvocationResult> {

    protected MdpInvocationResultDeserializer(Class<MdpInvocationResult> vc) {
        super(vc);
    }

    @SuppressWarnings("unchecked")
    public MdpInvocationResult deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
            JsonProcessingException {
        MdpInvocationResult deser = null;
        try {
            ObjectMapper mapper = JsonMessageConverter.getMapper();
            JsonNode jsonNode = jp.readValueAsTree();
            JsonNode valueNode = jsonNode.findValue("value");
            JsonNode excepNode = jsonNode.findValue("exception");
            Object value = null;
            Throwable exception = null;
            if (valueNode.asToken() != JsonToken.VALUE_NULL) {
                JsonNode type = jsonNode.findValue("valueType");
                if (type.asToken() == JsonToken.VALUE_STRING) {
                    value = mapper.readValue(valueNode, ClassUtils.forName(type.asText()));
                }
            }
            if (excepNode.asToken() != JsonToken.VALUE_NULL) {
                JsonNode excepType = jsonNode.findValue("exceptionType");
                exception = (Throwable) mapper.readValue(excepNode, ClassUtils.forName(excepType.asText()));
            }
            deser = new MdpInvocationResult(value, exception);
        } catch (ClassNotFoundException e) {
            ctxt.instantiationException(_valueClass, e);
        } catch (LinkageError e) {
            ctxt.instantiationException(_valueClass, e);
        }
        return deser;
    }
}
